﻿using Flurl.Http;
using Prism.Commands;
using Prism.Mvvm;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Windows.Input;
using TiaoTiaoCode.AutoUpdate.Common.Dtos;
using TiaoTiaoCode.AutoUpdate.Common.Responses;
using TiaoTiaoCode.AutoUpdate.ServerUI.Biz;
using TiaoTiaoCode.AutoUpdate.ServerUI.Models;
using TiaoTiaoCode.AutoUpdate.ServerUI.Splashs;
using TiaoTiaoCode.AutoUpdate.ServerUI.Views;
using TiaoTiaoCode.Common.Extensions;
using TiaoTiaoCode.Common.Helpers;

namespace TiaoTiaoCode.AutoUpdate.ServerUI.ViewModels
{
    public class MainProgramPublishViewModel : BindableBase
    {
        #region 字段

        const string PublishApi = "api/serverUI/publish";
        const string ScanFilesApi = "api/serverUI/scanFiles";
        const string QueryApi = "api/serverUI/query";

        readonly TiaoTiaoIniFile _iniFile;

        readonly SplashManager _loading;

        readonly IDialogService _dialogSer;

        #endregion

        #region 属性

        private ObservableCollection<MainProgramPublishItemView> publishData = default!;
        private string scanProgramName = default!;
        private List<string> appNames = default!;

        /// <summary>
        /// 发布的版本信息列表
        /// </summary>
        public ObservableCollection<MainProgramPublishItemView> PublishData
        {
            get { return publishData; }
            set { SetProperty(ref publishData, value); }
        }

        /// <summary>
        /// 扫描应用程序名
        /// </summary>
        public string ScanProgramName
        {
            get { return scanProgramName; }
            set { SetProperty(ref scanProgramName, value); }
        }

        /// <summary>
        /// 应用列表
        /// </summary>
        public List<string> AppNames
        {
            get { return appNames; }
            set { SetProperty(ref appNames, value); }
        }

        #endregion

        #region 命令

        ICommand? publishCommand;
        ICommand? scanFilesCommand;
        ICommand? uploadCommand;
        ICommand? appNamesDropdownOpenCommand;

        /// <summary>
        /// 发布命令
        /// </summary>
        public ICommand PublishCommand => publishCommand ?? (publishCommand = new DelegateCommand<object>(PublishVersion));

        /// <summary>
        /// 扫描应用程序文件
        /// </summary>
        public ICommand ScanFilesCommand => scanFilesCommand ?? (scanFilesCommand = new DelegateCommand(ScanFiles));

        /// <summary>
        /// 上传升级包
        /// </summary>
        public ICommand UploadCommand => uploadCommand ?? (uploadCommand = new DelegateCommand(UploadUpgrade));

        /// <summary>
        /// 应用程序名下拉列表展开事件
        /// </summary>
        public ICommand AppNamesDropdownOpenCommand => appNamesDropdownOpenCommand ?? (appNamesDropdownOpenCommand = new DelegateCommand(AppNamesDropDownOpen));

        #endregion

        public MainProgramPublishViewModel(SplashManager screenSplashLoading, IDialogService dialogService)
        {
            _loading = screenSplashLoading;
            _dialogSer = dialogService;

            _iniFile = new TiaoTiaoIniFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "setting.ini"));

            QueryAll();
        }

        #region 命令实现

        /// <summary>
        /// 发布/取消发布
        /// </summary>
        /// <param name="isPublish"></param>
        async void PublishVersion(object value)
        {
            if (!bool.TryParse(value.ToString(), out var isPublish)) return;

            var selectedData = PublishData.Where(t => t.IsSelected).ToList();

            selectedData.ForEach(t => t.IsPublish = isPublish);

            var baseApi = _iniFile.Read("application", "baseApi", String.Empty);
            var url = $"{baseApi.TrimEnd('/')}/{PublishApi}";

            var data = await url.PostJsonAsync(selectedData).ReceiveJson<ApiResponse<List<MainProgramView>>>();

            ConvertData(data.Data);
        }

        /// <summary>
        /// 扫描服务器文件
        /// </summary>
        async void ScanFiles()
        {
            if (ScanProgramName.TiaoTiaoIsNullOrEmpty()) return;

            var baseApi = _iniFile.Read("application", "baseApi", String.Empty);
            var url = $"{baseApi.TrimEnd('/')}/{ScanFilesApi}?programName={ScanProgramName}";

            _loading.ShowLoading("正在扫描文件....");

            await url.GetAsync();

            _loading.HideLoading();

            QueryAll(ScanProgramName);
        }

        /// <summary>
        /// 上传更新包弹窗
        /// </summary>
        void UploadUpgrade()
        {
            _dialogSer.ShowDialog(nameof(UploadPublishZipView), null, dr => { }, "NormalDialogWindow");
        }

        #endregion

        #region 

        /// <summary>
        /// 查询所有版本
        /// </summary>
        /// <param name="programName"></param>
        async void QueryAll(string? programName = null)
        {
            var baseApi = _iniFile.Read("application", "baseApi", String.Empty);
            var url = $"{baseApi.TrimEnd('/')}/{QueryApi}";

            var data = await url.PostJsonAsync(programName).ReceiveJson<ApiResponse<List<MainProgramView>>>();

            ConvertData(data.Data);
        }

        /// <summary>
        /// 转换为UI展示数据
        /// </summary>
        /// <param name="items"></param>
        void ConvertData(List<MainProgramView> items)
        {
            var lst = items.Select(t => new MainProgramPublishItemView
            {
                Id = t.Id,
                ProgramName = t.ProgramName,
                Major = t.Major,
                Version = t.Version,
                MinorNumber = t.MinorNumber,
                BuildNumber = t.BuildNumber,
                CustomVersion = t.CustomVersion,
                CreateDate = t.CreateDate,
                IsPublish = t.IsPublish
            }).ToList();

            PublishData = new ObservableCollection<MainProgramPublishItemView>(lst);
        }

        /// <summary>
        /// 获取应用App下拉
        /// </summary>
        async void AppNamesDropDownOpen()
        {
            var lst = await AppListBiz.QueryAll();

            AppNames = lst.Select(t => t.ProgramName).Cast<string>().ToList();
        }

        #endregion
    }
}
